﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Windows.Media;
using System.Windows;
using DataTier.Entities;

namespace Otgruzka.Export
{
    public class ConsAccOtgruzkaToExcel
    {
        public Common.Export.ExcelDocument Document { get; private set; }

        public ConsAccOtgruzkaToExcel()
        {
            var doc = prepareDocument(); // Создание пустого документа
            createStyles(doc); // Создание списка стилей, которые можно будет использовать в документе
            this.Document = doc;
        }


        private Common.Export.ExcelDocument prepareDocument()
        {
            var doc = new Common.Export.ExcelDocument();

            Common.Export.WindowProperties wp = new Common.Export.WindowProperties()
            {
                WindowHeight = 12015,
                WindowWidth = 19440,
                WindowTopX = 480,
                WindowTopY = 150
            };

            Common.Export.DocumentProperties dp = new Common.Export.DocumentProperties()
            {
                Author = "",
                LastAuthor = "",
                Company = "Компания МЕГА",
                Version = 1.00
            };

            doc.Header = new Common.Export.ExcelHeader()
            {
                WindowProperties = wp,
                DocumentProperties = dp
            };

            var workSheet = new Common.Export.Worksheet()
            {
                Name = "Отгрузка",
                Table = new Common.Export.Table()
            };


            doc.Worksheets.Add(workSheet);

            return doc;
        }


        /// <summary>
        /// Создание стилей для оформления документа
        /// </summary>
        /// <param name="doc"></param>
        private void createStyles(Common.Export.ExcelDocument doc)
        {
            var styleBold = new Common.Export.CellStyle()
            {
                ID = "bold",
                Borders = new Thickness(1),
                FontSize = 8,
                FontWeight = FontWeights.Bold,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                FontFamily = new FontFamily("Arial")
            };
            var styleBoldNonBorder = new Common.Export.CellStyle()
            {
                ID = "boldNonBorder",
                FontSize = 8,
                FontWeight = FontWeights.Bold,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                FontFamily = new FontFamily("Arial")
            };
            var style = new Common.Export.CellStyle()
            {
                ID = "normal",
                Borders = new Thickness(1, 1, 1, 1),
                FontSize = 8,
                FontWeight = FontWeights.Normal,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                FontFamily = new FontFamily("Arial")
            };
            var styleNormalNonBorder = new Common.Export.CellStyle()
            {
                ID = "normalNonBorder",
                FontSize = 8,
                FontWeight = FontWeights.Normal,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                FontFamily = new FontFamily("Arial")
            };
            var normalBold = new Common.Export.CellStyle()
            {
                ID = "normalBold",
                Borders = new Thickness(1, 1, 1, 1),
                FontSize = 8,
                FontWeight = FontWeights.Bold,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                FontFamily = new FontFamily("Arial")
            };
            var boldCenterHeadFoot = new Common.Export.CellStyle()
            {
                ID = "boldCenterHeadFoot",
                Borders = new Thickness(1),
                FontSize = 8,
                FontWeight = FontWeights.Bold,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                HorizontalAlignment = HorizontalAlignment.Center,
                FontFamily = new FontFamily("Arial")
            };
            var normalCenter = new Common.Export.CellStyle()
            {
                ID = "normalCenter",
                Borders = new Thickness(1, 1, 1, 1),
                FontSize = 8,
                FontWeight = FontWeights.Normal,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                HorizontalAlignment = HorizontalAlignment.Center,
                FontFamily = new FontFamily("Arial"),
                NumberFormat = "Standard"
            };
            var normalRight = new Common.Export.CellStyle()
            {
                ID = "normalRight",
                Borders = new Thickness(1, 1, 1, 1),
                FontSize = 8,
                FontWeight = FontWeights.Normal,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                HorizontalAlignment = HorizontalAlignment.Right,
                FontFamily = new FontFamily("Arial"),
                NumberFormat = "Standard"
            };

            var boldCenterRight = new Common.Export.CellStyle()
            {
                ID = "boldCenterRight",
                Borders = new Thickness(1, 1, 1, 1),
                FontSize = 8,
                FontWeight = FontWeights.Bold,
                TextWrapping = TextWrapping.Wrap,
                FontStyle = FontStyles.Normal,
                HorizontalAlignment = HorizontalAlignment.Right,
                FontFamily = new FontFamily("Arial"),
                NumberFormat = "Standard"
            };

            doc.Styles.Add(styleBold);
            doc.Styles.Add(styleBoldNonBorder);
            doc.Styles.Add(style);
            doc.Styles.Add(normalBold);
            doc.Styles.Add(styleNormalNonBorder);
            doc.Styles.Add(boldCenterHeadFoot);
            doc.Styles.Add(normalRight);
            doc.Styles.Add(boldCenterRight);
            doc.Styles.Add(normalCenter);
        }


        /// <summary>
        /// Оформление документа созданными стилями
        /// </summary>
        /// <param name="doc"></param>
        private void setStyles(Common.Export.ExcelDocument doc)
        {
            var tbl = doc.Worksheets[0].Table;

            tbl.BeforeRows.ForEach(row => row.Cells.ForEach(cell => cell.StyleID = "normalNonBorder"));
            tbl.BeforeRows[0].Cells.ForEach(cell => cell.StyleID = "boldNonBorder");
            tbl.HeaderRows.ForEach(row => row.Cells.ForEach(cell => cell.StyleID = "boldCenterHeadFoot"));
            tbl.Rows.ForEach(row => row.Cells.ForEach(cell => cell.StyleID = "normal"));

            for (int i = 0; i < tbl.Rows.Count; ++i)
            {
                if (tbl.Rows[i].Cells.Count > 0) tbl.Rows[i].Cells[0].StyleID = "normal";
                if (tbl.Rows[i].Cells.Count > 1) tbl.Rows[i].Cells[1].StyleID = "normalRight";
                if (tbl.Rows[i].Cells.Count > 2) tbl.Rows[i].Cells[2].StyleID = "normalRight";
            }
            if (tbl.Rows[tbl.Rows.Count - 1].Cells.Count > 0) tbl.Rows[tbl.Rows.Count - 1].Cells[0].StyleID = "normalBold";
            if (tbl.Rows[tbl.Rows.Count - 1].Cells.Count > 1) tbl.Rows[tbl.Rows.Count - 1].Cells[1].StyleID = "boldCenterRight";
            if (tbl.Rows[tbl.Rows.Count - 1].Cells.Count > 2) tbl.Rows[tbl.Rows.Count - 1].Cells[2].StyleID = "normalRight";
        }


        /// <summary>
        /// Создание столбцов и заголовков формируемого файла
        /// </summary>
        /// <param name="table"></param>
        /// <param name="data"></param>
        private void createExcelColumnsAndHeaders(Common.Export.Table table, ConsolidatedAccountOtgruzkaEntity entity)
        {
            int index = 1;

            table.Columns.Add(new Common.Export.Column() { AutoFitWidth = 1, Width = 248.2, Index = index++ });
            table.Columns.Add(new Common.Export.Column() { AutoFitWidth = 1, Width = 75.4, Index = index++ });
            table.Columns.Add(new Common.Export.Column() { AutoFitWidth = 1, Width = 230.0, Index = index++ });

            #region //Строки шапки, располагается над таблицей с данными
            table.BeforeRows.Add(new Common.Export.Row()
            {
                Cells = new List<Common.Export.Cell>() 
                { 
                    new Common.Export.Cell() { Type = "String" },
                    new Common.Export.Cell() { Data = "Отгрузка ", Type = "String", StyleID = "boldNonBorder" },
                }
            });
            table.BeforeRows.Add(new Common.Export.Row()
            {
                Cells = new List<Common.Export.Cell>() 
                { 
                    new Common.Export.Cell() { Data = "OОО \"Мегаофис\"", Type = "String", MergeAcross = 2 } 
                }
            });
            table.BeforeRows.Add(new Common.Export.Row()
            {
                Cells = new List<Common.Export.Cell>() 
                { 
                    new Common.Export.Cell() { Data = string.Format("Период: {0:dd.MM.yyyy} — {1:dd.MM.yyyy}", entity.PeriodDateStart, entity.PeriodDateEnd), MergeAcross = 2 } 
                }
            });
            table.BeforeRows.Add(new Common.Export.Row()
            {
                Cells = new List<Common.Export.Cell>() 
                { 
                    new Common.Export.Cell() { Data = string.Format("Контрагент: {0}", entity.JuridicalPerson.Name), MergeAcross = 2 } 
                }
            });
            #endregion //Строки шапки, располагается над таблицей с данными

            var headerrow = new Common.Export.Row();
            headerrow.Cells.Add(new Common.Export.Cell() { Data = "Номер заказа" });
            headerrow.Cells.Add(new Common.Export.Cell() { Data = "Сумма без НДС" });
            headerrow.Cells.Add(new Common.Export.Cell() { Data = "Центр затрат" });
            table.HeaderRows.Add(headerrow);
        }


        /// <summary>
        /// Заполнение документа данными
        /// </summary>
        /// <param name="table"></param>
        /// <param name="data"></param>
        private void appendExcelData(Common.Export.Table table, ConsolidatedAccountOtgruzkaEntity entity)
        {
            //double itogo = entity.OrderOtgruzkaList.Sum(o => (o.Summa - o.Summa * (1.0 - (1.0 / 1.18))));

            //double itogo = entity.OrderOtgruzkaList.Sum(o => (o.Summa - Math.Round(o.Summa, 2) * (1.0 - (1.0 / 1.18))));
            //double itogo = entity.OrderOtgruzkaList.Sum(o => (Math.Round(o.Summa, 2) - Math.Round(o.Summa, 2) * (1.0 - (1.0 / 1.18))));
            //double itogo = entity.OrderOtgruzkaList.Sum(o => Math.Round(Math.Round(o.Summa, 2) - Math.Round(o.Summa * (1.0 - (1.0 / 1.18)), 2), 2));
            //double nds = summa * (1 - (1 / 1.18));

            double itogo = entity.OrderOtgruzkaList.Sum(o => Math.Round(Math.Round(o.Summa, 2) - Math.Round(o.Summa, 2) * (1.0 - (1.0 / 1.18)), 2));
            double itogoWithNDS = entity.OrderOtgruzkaList.Sum(o => o.Summa);
            double itogoNotRound = Math.Round(itogoWithNDS - itogoWithNDS * (1.0 - (1.0 / 1.18)),2);
            double addedKopeika = Math.Round(itogoNotRound - itogo, 2); // Если сум ма НДС от общей суммы без округления не совпадает от того же, но с округлением, то прибавляем разницу в одну из строк и в итоговую сумму
            itogo += addedKopeika;
            int CostsCenterIdForAddedKopeika = entity.OrderOtgruzkaList.Where(o => o.Summa == entity.OrderOtgruzkaList.Max(oo => oo.Summa)).Select(o => o.CostsCenterId).FirstOrDefault();

            foreach (var item in entity.OrderOtgruzkaList)
            {
                double summa = (item.CostsCenterId == CostsCenterIdForAddedKopeika) ? item.Summa + addedKopeika : item.Summa;
                string costsCenter = item.CostsCenterName; // +"   " + item.CostsCenterId.ToString();

                var row = new Common.Export.Row();
                row.Cells.Add(new Common.Export.Cell()
                {
                    Data = string.Format("Заказ № {0}  от  {1:dd.MM.yyyy}    (счет № {2}  от  {3:dd.MM.yyyy})",
                                item.Orders[0].Number, item.Orders[0].CreatedDate, item.Orders[0].AccountNumber, item.Orders[0].AccountCreatedDate),  // Заказ № 124  от  30.10.2012    (счет № P 104  от  30.10.2012) 
                    Type = "String"
                });
                row.Cells.Add(new Common.Export.Cell()
                {
                    Data = (summa - (summa * (1.0 - (1.0 / 1.18)))).ToString("#00.00").Replace(",", "."),
                    Type = "Number",
                    MergeDown = (item.Orders.Count() > 1) ? (item.Orders.Count() -1) : 0
                });
                row.Cells.Add(new Common.Export.Cell()
                {
                    Data = costsCenter,
                    Type = "String",
                    MergeDown = (item.Orders.Count() > 1) ? (item.Orders.Count() - 1) : 0
                });
                table.Rows.Add(row);
                for (int i = 1; i < item.Orders.Count(); i++)
                {
                    var rowDown = new Common.Export.Row();
                    rowDown.Cells.Add(new Common.Export.Cell()
                    {
                        Data = string.Format("Заказ № {0}  от  {1:dd.MM.yyyy}    (счет № {2}  от  {3:dd.MM.yyyy})",
                                    item.Orders[i].Number, item.Orders[i].CreatedDate, item.Orders[i].AccountNumber, item.Orders[i].AccountCreatedDate),  // Заказ № 124  от  30.10.2012    (счет № P 104  от  30.10.2012) 
                        Type = "String"
                    });
                    table.Rows.Add(rowDown);
                }
            }

            #region // Старая версия
            //table.Rows.AddRange(entity.OrderOtgruzkaList.Select(row =>
            //{
            //    var result = new Common.Export.Row();
            //    result.Cells.Add(new Common.Export.Cell()
            //    {
            //        Data = string.Format("Заказ № 124  от  30.10.2012    (счет № P 104  от  30.10.2012)", row), //Заказ № 124  от  30.10.2012    (счет № P 104  от  30.10.2012) 
            //        Type = "String"
            //    });
            //    result.Cells.Add(new Common.Export.Cell()
            //    {
            //        Data = (row.Summa - (row.Summa * (1.0 - (1.0 / 1.18)))).ToString("#00.00").Replace(",", "."),
            //        Type = "Number"
            //    });
            //    result.Cells.Add(new Common.Export.Cell()
            //    {
            //        Data = row.CostsCenterName,
            //        Type = "String"
            //    });
            //    return result;
            //}).ToArray());
            #endregion // Старая версия

            // Строка с ИТОГО
            table.Rows.Add(
                new Common.Export.Row()
                {
                    Cells = new List<Common.Export.Cell>()
                    {
                        new Common.Export.Cell() { Data = "Итого без НДС:", Type = "String" },
                        new Common.Export.Cell()
                        {
                            Data = itogo.ToString("#00.00").Replace(",", "."),
                            Type = "Number"
                        },
                        new Common.Export.Cell() { Data = "", Type = "String" }
                    }
                }
            );
        }



        public Common.Export.ExcelDocument CreateDocument(ConsolidatedAccountOtgruzkaEntity entity)
        {
            createExcelColumnsAndHeaders(this.Document.Worksheets[0].Table, entity);
            appendExcelData(this.Document.Worksheets[0].Table, entity);
            setStyles(this.Document);

            return this.Document;
        }



    }
}